package com.shop.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mysql.cj.xdevapi.Client;
import com.shop.common.NoUtil;
import com.shop.common.TokenUtil;
import com.shop.common.result.Result;
import com.shop.common.result.util.ResultModel;
import com.shop.entity.*;
import com.shop.mapper.*;
import com.shop.mapper.ext.BaseOrderDetailDoMapperExt;
import com.shop.mapper.ext.CommodityWarehouseRelationDoMapperExt;
import com.shop.mapper.ext.FactoryCommodityExtendDoMapperExt;
import com.shop.service.SellerCommodityExtendService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.shopEnum.BaseOrderEnum;
import com.shop.shopEnum.NoEnum;
import com.shop.shopEnum.PayTypeEnum;
import com.shop.shopEnum.YesOrNoEnum;
import com.shop.vo.seller.AddSellerCommodityExtendVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 卖家商品扩展表 服务实现类
 * </p>
 *
 * @author 靳 旺
 * @since 2021-03-17
 */
@Service
public class SellerCommodityExtendServiceImpl extends ServiceImpl<SellerCommodityExtendDoMapper, SellerCommodityExtendDo> implements SellerCommodityExtendService {

    @Autowired
    private FactoryCommodityExtendDoMapperExt factoryCommodityExtendDoMapperExt;

    @Autowired
    private ClientDoMapper clientDoMapper;

    @Autowired
    private BaseOrderDoMapper baseOrderDoMapper;

    @Autowired
    private ShopDoMapper shopDoMapper;

    @Autowired
    private BaseOrderDetailDoMapperExt baseOrderDetailDoMapperExt;

    @Autowired
    private BaseOrderDetailDoMapper baseOrderDetailDoMapper;

    @Autowired
    private CommodityWarehouseRelationDoMapperExt commodityWarehouseRelationDoMapperExt;

    @Autowired
    private ShopWarehoseRelationDoMapper shopWarehoseRelationDoMapper;

    @Autowired
    private WarehouseInfoDoMapper warehouseInfoDoMapper;


    @Override
    public ResultModel addSellerCommodityExtendVo(List<AddSellerCommodityExtendVo> addSellerCommodityExtendVoList) throws Exception {
        /* 1、获取工厂商品信息 */
        List<FactoryCommodityExtendDo> factoryCommodityExtendDoList = this.selectFactoryCommodity(addSellerCommodityExtendVoList.stream().map(AddSellerCommodityExtendVo::getPkCommodityId).collect(Collectors.toList()));
        /* 2、工厂商品外键key  工厂商品信息集合为val 转map*/
        Map<Long, List<FactoryCommodityExtendDo>> map = factoryCommodityExtendDoList.stream().collect(Collectors.groupingBy(FactoryCommodityExtendDo::getFkCommodityId));
        /* 3、计算价格和优惠金额 */
        Map<String, BigDecimal> priceAndPreferential = this.computePriceAndPreferential(factoryCommodityExtendDoList, addSellerCommodityExtendVoList);
        /* 4、添加订单 */
        BaseOrderDo baseOrderDo = this.addBaseOrder(priceAndPreferential);
        /* 5、添加订单详情 */
        this.addBaseOrderDetail(addSellerCommodityExtendVoList, baseOrderDo, map);

        return Result.successResultModel(baseOrderDo.getPkBaseOrderId());
    }

    @Override
    public ResultModel paySuccessMessage(String out_trade_no, String trade_no, String trade_status) throws Exception {
        /* 1、校验订单号 */
        if (!trade_status.equals(BaseOrderEnum.TRADESUCCESS.code)) return Result.errorResultModel("订单交易失败！");
        /* 2、获取对应订单 */
        BaseOrderDo baseOrderDo = this.selectBaseOrder(out_trade_no);
        if (baseOrderDo == null) return Result.errorResultModel("订单回写未找到订单！");
        /* 3、获取对应订单详情 */
        List<BaseOrderDetailDo> baseOrderDetailDos = this.tardeBaseOrderDetail(baseOrderDo.getPkBaseOrderId());
        if (baseOrderDetailDos.size() <= 0) return Result.errorResultModel("订单回写未找到订单详情！");
        /* 4、查询商户默认仓库 */
        Long warehouseId = this.defaultWarehouse(baseOrderDo.getFkClientId());
        /* 5、将商品添加进仓库 */
        this.addCommodityToWarehouseInfo(baseOrderDetailDos, warehouseId);
        /* 6、修改订单支付交易号 */
        baseOrderDo.setTradeNo(trade_no);
        baseOrderDoMapper.updateById(baseOrderDo);

        return Result.successResultModel();
    }

    private void addBaseOrderDetail(List<AddSellerCommodityExtendVo> addSellerCommodityExtendVoList, BaseOrderDo baseOrderDo, Map<Long, List<FactoryCommodityExtendDo>> map) throws Exception {
        ShopDo shopDo = this.getShop();
        List<Long> ids = addSellerCommodityExtendVoList.stream().map(AddSellerCommodityExtendVo::getPkCommodityId).collect(Collectors.toList());
        Map<Long, List<CommodityWarehouseRelationDo>> commodityWarehouseRelationMap = this.getCommodityWarehouseRelation(ids).stream().collect(Collectors.groupingBy(CommodityWarehouseRelationDo::getFkCommodityId));
        List<BaseOrderDetailDo> baseOrderDetailDoList = addSellerCommodityExtendVoList.stream().map(k -> {
            BaseOrderDetailDo baseOrderDetailDo = new BaseOrderDetailDo();
            baseOrderDetailDo.setFkBaseOrderId(baseOrderDo.getPkBaseOrderId());
            baseOrderDetailDo.setFkCommodityId(k.getPkCommodityId());
            baseOrderDetailDo.setFkCommodityColorId(k.getPkCommodityColorId());
            baseOrderDetailDo.setFkCommoditySizeId(k.getPkCommoditySizeId());
            baseOrderDetailDo.setFkMerchantsId(shopDo.getPkShopId());
            baseOrderDetailDo.setDistrict(JSON.toJSONString(k.getPkClientOrderGoodsAddressIds()));
            baseOrderDetailDo.setFkExpressId(k.getFkExpressId());
            baseOrderDetailDo.setAddress(k.getAddress());
            baseOrderDetailDo.setCommodityNumber(k.getNumber());
            baseOrderDetailDo.setFkWarehouseInfoId(commodityWarehouseRelationMap.get(k.getPkCommodityId()).get(0).getFkWarehouseInfoId());
            baseOrderDetailDo.setCommodityPrice(map.get(k.getPkCommodityId()).get(0).getPrice());
            baseOrderDetailDo.setIsPayment(YesOrNoEnum.NO.code);
            baseOrderDetailDo.setSingFor(YesOrNoEnum.NO.code);
            baseOrderDetailDo.setCreateId(TokenUtil.getUserId());
            return baseOrderDetailDo;
        }).collect(Collectors.toList());
        if (baseOrderDetailDoMapperExt.beachInsert(baseOrderDetailDoList) <= 0)
            throw new Exception("添加订单详情失败！");
    }

    /**
     * 添加订单
     *
     * @param priceAndPreferential
     * @return
     * @throws Exception
     */
    private BaseOrderDo addBaseOrder(Map<String, BigDecimal> priceAndPreferential) throws Exception {
        BaseOrderDo baseOrderDo = new BaseOrderDo();
        baseOrderDo.setBaseOrderNo(NoUtil.generator(NoEnum.BRAGE));
        baseOrderDo.setFkClientId(TokenUtil.getUserId());
        baseOrderDo.setCreateId(TokenUtil.getUserId());
        baseOrderDo.setPaymentMethod(PayTypeEnum.ALIPAY.type);
        baseOrderDo.setOrderMoney(priceAndPreferential.get("price"));
        baseOrderDo.setDistrictMoney(priceAndPreferential.get("preferential"));
        baseOrderDo.setPaymentMoney(priceAndPreferential.get("price").subtract(priceAndPreferential.get("preferential")));
        baseOrderDo.setOrderStatus(BaseOrderEnum.UNPAIN.code);
        baseOrderDo.setShippingUser(this.getClient().getClientName());
        baseOrderDo.setCreateId(TokenUtil.getUserId());
        if (baseOrderDoMapper.insert(baseOrderDo) <= 0)
            throw new Exception("添加订单失败！");
        return baseOrderDo;
    }

    /**
     * 获取厂家商品
     *
     * @param pkCommodityIds
     * @return
     * @throws Exception
     */
    public List<FactoryCommodityExtendDo> selectFactoryCommodity(List<Long> pkCommodityIds) throws Exception {
        if (pkCommodityIds.size() <= 0) return null;
        return factoryCommodityExtendDoMapperExt.selectFactoryCommodity(pkCommodityIds);
    }

    /**
     * 获取店铺
     *
     * @return
     */
    private ShopDo getShop() {
        QueryWrapper<ShopDo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fk_client_id", TokenUtil.getUserId());
        return shopDoMapper.selectOne(queryWrapper);
    }

    /**
     * 获取客户
     *
     * @return
     */
    private ClientDo getClient() {
        return clientDoMapper.selectById(TokenUtil.getUserId());
    }

    /**
     * 获取商品价格和优惠
     *
     * @param factoryCommodityExtendDos
     * @return
     */
    private Map<String, BigDecimal> computePriceAndPreferential(List<FactoryCommodityExtendDo> factoryCommodityExtendDos, List<AddSellerCommodityExtendVo> addSellerCommodityExtendVoList) {
        Map<String, BigDecimal> map = new HashMap<>();
        /* 1、价格总和 */
        Map<Long, List<AddSellerCommodityExtendVo>> longListMap = addSellerCommodityExtendVoList.stream().collect(Collectors.groupingBy(AddSellerCommodityExtendVo::getPkCommodityId));
        BigDecimal price = factoryCommodityExtendDos.stream().map(k -> {
            List<AddSellerCommodityExtendVo> addSellerCommodityExtendVos = longListMap.get(k.getFkCommodityId());
            if (addSellerCommodityExtendVos != null)
                return new BigDecimal(addSellerCommodityExtendVos.get(0).getNumber()).multiply(k.getPrice());
            return new BigDecimal(0);
        }).collect(Collectors.toList()).stream().reduce(BigDecimal.ZERO, BigDecimal::add);

        /* 2、优惠总和 */
        BigDecimal preferential = factoryCommodityExtendDos.stream().map(FactoryCommodityExtendDo::getPreferential).reduce(BigDecimal.ZERO, BigDecimal::add);

        map.putIfAbsent("price", price);
        map.putIfAbsent("preferential", preferential);
        return map;
    }


    /**
     * 获取厂家商品仓库信息
     *
     * @param fkCommodityIds
     * @return
     * @throws Exception
     */
    public List<CommodityWarehouseRelationDo> getCommodityWarehouseRelation(List<Long> fkCommodityIds) throws Exception {
        return commodityWarehouseRelationDoMapperExt.selectCommodityWarehouseRelation(fkCommodityIds);
    }

    /**
     * 订单支付成功 根据订单编号查找订单
     *
     * @param out_trade_no
     * @return
     */
    private BaseOrderDo selectBaseOrder(String out_trade_no) {
        QueryWrapper<BaseOrderDo> baseOrderDoQueryWrapper = new QueryWrapper<>();
        baseOrderDoQueryWrapper.eq("base_order_no", out_trade_no);
        return baseOrderDoMapper.selectOne(baseOrderDoQueryWrapper);
    }

    /**
     * 订单支付成功 根据订单号查找订单详情
     *
     * @param baseOrderId
     * @return
     */
    private List<BaseOrderDetailDo> tardeBaseOrderDetail(Long baseOrderId) throws Exception {
        QueryWrapper<BaseOrderDetailDo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fk_base_order_id", baseOrderId);
        return baseOrderDetailDoMapper.selectList(queryWrapper);
    }


    /**
     * 查询商铺默认仓库
     *
     * @param fkClientId
     * @return
     * @throws Exception
     */
    private Long defaultWarehouse(Long fkClientId) throws Exception {
        QueryWrapper<ShopDo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fk_client_id", fkClientId);
        ShopDo shopDo = shopDoMapper.selectOne(queryWrapper);
        Assert.notNull(shopDo, "您不是商家！");
        QueryWrapper<ShopWarehoseRelationDo> warehoseRelationDoQueryWrapper = new QueryWrapper<>();
        warehoseRelationDoQueryWrapper.eq("fk_shop_id",shopDo.getPkShopId());
        List<ShopWarehoseRelationDo> shopWarehoseRelationDos = shopWarehoseRelationDoMapper.selectList(warehoseRelationDoQueryWrapper);
        if (shopWarehoseRelationDos.size() <= 0) throw new Exception("您没有仓库");
        List<Long> warehouseInfoIds = shopWarehoseRelationDos.stream().map(ShopWarehoseRelationDo::getFkWarehoseInfoId).collect(Collectors.toList());
        List<WarehouseInfoDo> warehouseInfoDos = warehouseInfoDoMapper.selectBatchIds(warehouseInfoIds);
        List<WarehouseInfoDo> warehouseInfoList = warehouseInfoDos.stream().filter(k -> k.getWarehouseStatus().equals(YesOrNoEnum.YES.code)).collect(Collectors.toList());
        return warehouseInfoList.get(0).getPkWarehouseInfoId();
    }


    /**
     * 将商品放入默认仓库
     *
     * @throws Exception
     */
    private void addCommodityToWarehouseInfo(List<BaseOrderDetailDo> baseOrderDetailDos, Long warehouseId) throws Exception {
        List<CommodityWarehouseRelationDo> commodityWarehouseRelationDos = baseOrderDetailDos.stream().map(k -> {
            CommodityWarehouseRelationDo commodityWarehouseRelationDo = new CommodityWarehouseRelationDo();
            commodityWarehouseRelationDo.setFkCommodityId(k.getFkCommodityId());
            commodityWarehouseRelationDo.setFkCommodityColorId(k.getFkCommodityColorId());
            commodityWarehouseRelationDo.setFkCommoditySizeId(k.getFkCommoditySizeId());
            commodityWarehouseRelationDo.setCreateId(TokenUtil.getUserId());
            commodityWarehouseRelationDo.setFkWarehouseInfoId(warehouseId);
            commodityWarehouseRelationDo.setCurrentCommodityNumber(k.getCommodityNumber());
            return commodityWarehouseRelationDo;
        }).collect(Collectors.toList());

        if (commodityWarehouseRelationDoMapperExt.beachInsert(commodityWarehouseRelationDos) <= 0)
            throw new Exception("更新仓库失败！");

    }


}
